/**
    算法描述：
    核心问题：
    解决所需数据结构+算法：
**/
#include<bits/stdc++.h>
using namespace std;
 
struct edge{
    int x, y, c, pre, other;
}a[410];
int alen = 0, last[410] = {0};
int st, ed, h[210] = {0};
 
void ins(int x, int y, int c) {
    a[++alen] = edge{x, y, c, last[x], alen+1};
    last[x] = alen;
    a[++alen] = edge{y, x, 0, last[y], alen-1};
    last[y] = alen;
}
 
bool bfs() {
//  需要得到图的生成树高度，因此必须通过bfs获得
//  初始化这里十分必要，因为每次的 bfs 梯度要变化 
    memset(h, 0, sizeof(h));
    queue<int> q;
    q.push(st);
    h[st] = 1;
    while(!q.empty()) {
        int x = q.front();
        for (int k=last[x]; k; k=a[k].pre) {
            int y = a[k].y;
            if (!h[y] && a[k].c>0) {
                h[y] = h[x] + 1;
                q.push(y);
            }
        }
        q.pop();
    }
    return h[ed] > 0;
}
 
int findflow(int x, int flow) {
//  flow是进来的流量，sx是分出去的流量 
    int sx = 0;
    if (x == ed)
        return flow;
    for (int k=last[x]; k; k=a[k].pre) {
        int y = a[k].y;
        if (a[k].c>0 && h[y]==h[x]+1 && sx<flow) {
            int sy = findflow(y, min(a[k].c, flow-sx));//能分出去的最大流量 
            a[k].c -= sy;
            a[a[k].other].c += sy;
            sx += sy;
        }
    }
    if (sx == 0)
        h[x] = 0;
    return sx;
}
 
int main() {
    int m, n, ans = 0;
    scanf("%d%d", &m, &n);
    while(m--) {
        int x, y, c;
        scanf("%d%d%d", &x, &y, &c);
        ins(x, y, c);
    }
    st = 1; ed = n;
    while(bfs())
        ans += findflow(st, 0x3fffffff);
    printf("%d\n", ans);
     
    return 0;
}